package cn.iocoder.yudao.module.promotion.gift.dao;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.business.basic.dao.mapper.CoreMapper;
import cn.iocoder.yudao.framework.business.basic.dao.query.CoreLambdaQueryWrapper;
import cn.iocoder.yudao.module.api.promotion.gift.enums.GiftBizType;
import cn.iocoder.yudao.module.api.promotion.gift.enums.GiftRecordStatus;
import cn.iocoder.yudao.module.promotion.gift.pojo.bo.GiftRecordCountBO;
import cn.iocoder.yudao.module.promotion.gift.pojo.po.GiftRecord;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;

@Mapper
public interface GiftRecordMapper extends CoreMapper<GiftRecord> {

    default GiftRecord selectByUserIdAndId(Long userId, Long id) {
        return selectOne(GiftRecord::getUserId, userId, GiftRecord::getId, id);
    }

    @Select("""
            <script>
            SELECT gift_activity_id, COUNT(1) AS count
            FROM promotion_gift_record
            WHERE user_id = #{userId} AND status <![CDATA[ <> ]]> 0 AND gift_activity_id IN
            <foreach item="id" collection="giftActivityIds" open="(" separator="," close=")">
                #{id}
            </foreach>
            GROUP BY gift_activity_id
            </script>
            """)
    List<GiftRecordCountBO> selectCountByUserId(@Param("userId") Long userId, @Param("giftActivityIds") Collection<Long> giftActivityIds);

    default int selectReceivedCountByUserIdAndGiftActivityId(Long userId, Long giftActivityId) {
        CoreLambdaQueryWrapper<GiftRecord> wrapper = new CoreLambdaQueryWrapper<>();
        wrapper.eq(GiftRecord::getUserId, userId);
        wrapper.eq(GiftRecord::getGiftActivityId, giftActivityId);
        wrapper.ne(GiftRecord::getStatus, GiftRecordStatus.PENDING.getValue());
        Long count = selectCount(wrapper);
        if (count == null) {
            return 0;
        }
        return count.intValue();
    }

    default int selectCountByUserIdAndStatus(Long userId, Integer status) {
        CoreLambdaQueryWrapper<GiftRecord> wrapper = new CoreLambdaQueryWrapper<>();
        wrapper.eq(GiftRecord::getUserId, userId);
        wrapper.eqIfPresent(GiftRecord::getStatus, status);
        Long count = selectCount(wrapper);
        if (count == null) {
            return 0;
        }
        return count.intValue();
    }

    default boolean exists(Long userId, GiftBizType bizType, Long bizOrderId) {
        return exists(new CoreLambdaQueryWrapper<GiftRecord>()
                .eq(GiftRecord::getUserId, userId)
                .eq(GiftRecord::getBizType, bizType)
                .eq(GiftRecord::getBizId, bizOrderId));
    }

    default List<GiftRecord> selectListByStatusAndExpireTimeLe(Integer status, LocalDateTime expireTime) {
        return selectList(new CoreLambdaQueryWrapper<GiftRecord>()
                .eq(GiftRecord::getStatus, status)
                .le(GiftRecord::getExpireTime, expireTime)
        );
    }

    default int updateByIdAndStatus(Long id, Integer status, GiftRecord updateObj) {
        return update(updateObj, new LambdaUpdateWrapper<GiftRecord>()
                .eq(GiftRecord::getId, id).eq(GiftRecord::getStatus, status));
    }

    default List<GiftRecord> selectGrantedByTradeNo(String tradeNo) {
        List<GiftRecord> list = selectList(new CoreLambdaQueryWrapper<GiftRecord>()
                .eq(GiftRecord::getTradeNo, tradeNo)
                .in(GiftRecord::getStatus, GiftRecordStatus.PENDING.getValue(), GiftRecordStatus.TAKEN.getValue())
        );
        if (CollUtil.isEmpty(list)) {
            return List.of();
        }
        return list;
    }

}